// VCircle.cpp
//
#include "VCircle.h"

#include "OpenGL/Renderer.h"
#include "OpenGL/Selection.h"
#include "OpenGL/OpenGL.h"

#include <iostream>

#include "MemCheck.h"

// ------------------------------------------------------------------------------------------------
VCircle::VCircle()
{}

// ------------------------------------------------------------------------------------------------
VCircle::VCircle( const OpenGL::Math::dvec3 &center, double radius )
: _center(center),
  _radius(radius)
{
	_circle = gluNewQuadric();

	_boundingBox = OpenGL::Math::box3( OpenGL::Math::dvec3(_center)-radius,OpenGL::Math::dvec3(_center)+radius );
}

// ------------------------------------------------------------------------------------------------
VCircle::~VCircle()
{
	gluDeleteQuadric(_circle);
}


// ------------------------------------------------------------------------------------------------
VObject::ObjectType VCircle::type() const		{ return Shape; }

// ------------------------------------------------------------------------------------------------
std::vector<OpenGL::Math::dvec3> VCircle::snapPoints() const
{
	std::vector<OpenGL::Math::dvec3> pts;
	pts.push_back( _center );

	return pts;
}

// ------------------------------------------------------------------------------------------------
OpenGL::Math::dvec3 VCircle::textPosition() const
{
	return _center;
}

// ------------------------------------------------------------------------------------------------
void VCircle::draw( OpenGL::Renderer *r ) const
{
	OpenGL::Math::dvec3 o = _center - r->origin();

	glPushMatrix();
		glTranslated( o.x,o.y,o.z );
		
		glColor4fv( color().transparent().rgba() );
		gluQuadricDrawStyle( _circle,GLU_FILL );
		gluDisk(_circle,0,_radius,64,1);

		glLineWidth(2.f);
		glColor4fv( color().rgba() );
		gluQuadricDrawStyle( _circle,GLU_SILHOUETTE );
		gluDisk(_circle,0,_radius,64,1);
	glPopMatrix();


	//OpenGL::Math::box3 box = _boundingBox.translated(-r->origin());

	//// fill
	//glColor4fv( color().transparent().rgba() );
	//glBegin( GL_TRIANGLE_STRIP );
	//	glVertex2d( box.minPoint().x, box.maxPoint().y );
	//	glVertex2d( box.minPoint().x, box.minPoint().y );
	//	glVertex2d( box.maxPoint().x, box.maxPoint().y );
	//	glVertex2d( box.maxPoint().x, box.minPoint().y );
	//glEnd();

	//// borders
	//glLineWidth(2.f + (isHilighted() * .5f) );
	//glColor4fv( color().rgba() );
	//glBegin( GL_LINE_LOOP);
	//	glVertex2d( box.minPoint().x, box.maxPoint().y );
	//	glVertex2d( box.minPoint().x, box.minPoint().y );
	//	glVertex2d( box.maxPoint().x, box.minPoint().y );
	//	glVertex2d( box.maxPoint().x, box.maxPoint().y );
	//glEnd();

	//glPopAttrib();
}

// ------------------------------------------------------------------------------------------------
void VCircle::drawForSelection( OpenGL::Renderer *r ) const
{
	OpenGL::Selection::Name name( _id );

	OpenGL::Math::dvec3 o = _center - r->origin();


	glPushMatrix();
		glTranslated( o.x,o.y,o.z );
		
		glColor4fv( color().transparent().rgba() );
		gluQuadricDrawStyle( _circle,GLU_FILL );
		gluDisk(_circle,0,_radius,64,1);
	glPopMatrix();
}

// ------------------------------------------------------------------------------------------------
bool VCircle::intersects( const OpenGL::Math::box3 &b ) const
{
	OpenGL::Math::dvec3 dist;
	dist.x = OpenGL::Math::abs( _center.x-b.center().x );
	dist.y = OpenGL::Math::abs( _center.y-b.center().y );

	const double rw = b.sizes().x;
	const double rh = b.sizes().y;

	if( dist.x > (rw/2 + _radius) )	return false;
    if( dist.y > (rh/2 + _radius) ) return false;

    if( dist.x <= (rw/2) )	return true;
    if( dist.y <= (rh/2) )	return true;

    double cornerDistance_sq = (dist.x - rw/2)*(dist.x - rw/2) + (dist.y - rh/2)*(dist.y - rh/2);

    return (cornerDistance_sq <= (_radius*_radius));

	//std::vector<OpenGL::Math::dvec3> corners;
	//corners.push_back( OpenGL::Math::dvec3(b.minPoint().x,b.minPoint().y, 0) );
	//corners.push_back( OpenGL::Math::dvec3(b.maxPoint().x,b.minPoint().y, 0) );
	//corners.push_back( OpenGL::Math::dvec3(b.maxPoint().x,b.maxPoint().y, 0) );
	//corners.push_back( OpenGL::Math::dvec3(b.minPoint().x,b.maxPoint().y, 0) );

	//bool intersect = false;
	//for( size_t i=0; i<corners.size(); ++i )
	//{
	//	if( OpenGL::Math::distance(_center,corners[i]) < _radius )
	//	{
	//		intersect = true;
	//		break;
	//	}
	//}
	//
	//return intersect;
}
